package service

import (
	"go-web-app-demo/common"
	"go-web-app-demo/dao/db"
	"go-web-app-demo/dao/redis"
	"go-web-app-demo/model"
	"strconv"
)

type PostDetails struct {
	Post      *db.Post      `json:"post"`
	User      *db.User      `json:"user"`
	Community *db.Community `json:"community"`
}

func NewPost(req *model.CreatePostRequest) *common.Result {

	tx, txerr := db.DB.Beginx()

	if txerr != nil {
		return common.NewFailed(txerr.Error())
	}

	v, err := db.NewPost(req)

	if err != nil {
		return common.NewFailed(err.Error())
	}

	if err = redis.NewPost(strconv.FormatUint(v, 10), strconv.FormatUint(req.CommunityID, 10)); err != nil {
		_ = tx.Rollback()
		return common.NewFailed(err.Error())
	}

	_ = tx.Commit()
	return common.NewSucceed(v)
}

func GetPost(pid uint64) *common.Result {

	p, err := db.GetPostById(pid)

	if err != nil {
		return common.NewFailed(err.Error())
	}

	u, err := db.GetByUserId(p.AuthorID)

	if err != nil {
		return common.NewFailed(err.Error())
	}

	c, err := db.GetCommunityByID(p.CommunityID)

	if err != nil {
		return common.NewFailed(err.Error())
	}

	pd := &PostDetails{
		Post:      p,
		User:      u,
		Community: c,
	}

	return common.NewSucceed(pd)
}

func ListPostPage(offset uint64, limit uint64, cid uint64, orderby string) *common.Result {

	pds := make([]*PostDetails, 0, limit)

	if "time" == orderby {
		posts, err := db.ListPostPage(cid, offset, limit)

		if err != nil {
			return common.NewFailed(err.Error())
		}

		for _, v := range posts {
			u, _ := db.GetByUserId(v.AuthorID)
			c, _ := db.GetCommunityByID(v.CommunityID)
			pd := &PostDetails{
				Post:      v,
				User:      u,
				Community: c,
			}

			pds = append(pds, pd)
		}
	} else if "score" == orderby {
		ids, err := redis.ListPostID(cid, offset, limit)
		if err != nil {
			return common.NewFailed(err.Error())
		}

		posts, err := db.ListPostByIds(ids)

		if err != nil {
			return common.NewFailed(err.Error())
		}

		for _, v := range posts {
			u, _ := db.GetByUserId(v.AuthorID)
			c, _ := db.GetCommunityByID(v.CommunityID)
			pd := &PostDetails{
				Post:      v,
				User:      u,
				Community: c,
			}

			pds = append(pds, pd)
		}
	}

	return common.NewSucceed(pds)
}
